﻿using MDT_Metro_monitoring.Common;

using System;
using System.Collections.Generic;
using System.IO;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

using MDT_MonitorModel;
using Windows.Storage.Streams;
using System.Xml.Serialization;
using Windows.Storage;

// The Grid App template is documented at http://go.microsoft.com/fwlink/?LinkId=234226

namespace MDT_Metro_monitoring
{
    /// <summary>
    /// Fournit un comportement spécifique à l'application afin de compléter la classe Application par défaut.
    /// </summary>
    sealed partial class App : Application
    {

        private static List<ODataSampleViewModel> applicationViewModel;
        private static List<Server> servers;
        private static string ServerConfigurationFile = @"data\servers.xml";


        /// <summary>
        /// Initializes the singleton Application object.  This is the first line of authored code
        /// à être exécutée. Elle correspond donc à l'équivalent logique de main() ou WinMain().
        /// </summary>
        public App()
        {
            this.InitializeComponent();
            this.Suspending += OnSuspending;
            
            App.updateAvailable = true;
            App.preloadComputer();

        }

        private static async void preloadComputer()
        {
            if (App.servers != null)
            {
                foreach (Server srv in App.Servers)
                {
                    if (srv.Online)
                    {
                        srv.Clients = (List<Computer>)await srv.ClientData.LoadComputersAsync();
                    }
                }
            }
        }

        internal static List<Server> Servers
        {
            get
            {
                if (servers == null)
                {
                    readServersData();
                }

                return servers;
            }
        }

        internal async static void readServersData()
        {
            StorageFile file = null;
            try
            {
               file = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFileAsync(App.ServerConfigurationFile);
            }
            catch (FileNotFoundException)
            {
                
            }
            if (file != null)
            {
                IRandomAccessStreamWithContentType ras = await file.OpenReadAsync();
                Stream asStream = ras.AsStream();

                XmlSerializer serializer = new XmlSerializer(typeof(List<Server>));
                try
                {
                    servers = (List<Server>)serializer.Deserialize(asStream);
                    asStream.Dispose();
                }
                catch (InvalidOperationException)
                {
                    Windows.Storage.ApplicationData.Current.ClearAsync();
                }
            }
        }

        internal async static void writeServerData()
        {
            StorageFile file = null;
            
            
            
            try
            {
                
                file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync(App.ServerConfigurationFile,
       Windows.Storage.CreationCollisionOption.OpenIfExists);
            }
            catch(FileNotFoundException)
            {
                
            }
            if (file != null)
            {
                Stream asStream = await file.OpenStreamForWriteAsync();

                XmlSerializer serializer = new XmlSerializer(typeof(List<Server>));
                serializer.Serialize(asStream, servers);
                asStream.Dispose();
            }
        }

        internal static List<ODataSampleViewModel> ViewModel
        {
            get
            {
                {
                    applicationViewModel = new List<ODataSampleViewModel>();
                    foreach (Server s in Servers)
                    {
                        if (s.Online)
                            applicationViewModel.Add(s.ClientData);
                    }
                }
                
                return applicationViewModel;
            }
        }

        /// <summary>
        /// Invoqué lorsque l'application est lancée normalement par l'utilisateur final. D'autres points d'entrée
        /// sont utilisés lorsque l'application est lancée pour ouvrir un fichier spécifique, pour afficher
        /// des résultats de recherche, etc.
        /// </summary>
        /// <param name="args">Détails concernant la requête et le processus de lancement.</param>
        protected override async void OnLaunched(LaunchActivatedEventArgs args)
        {
            Frame rootFrame = Window.Current.Content as Frame;

            // Do not repeat app initialization when the Window already has content,
            // just ensure that the window is active

            if (rootFrame == null)
            {
                // Create a Frame to act as the navigation context and navigate to the first page
                rootFrame = new Frame();
                //Associate the frame with a SuspensionManager key                                
                SuspensionManager.RegisterFrame(rootFrame, "AppFrame");

                if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    // Restore the saved session state only when appropriate
                    try
                    {
                        await SuspensionManager.RestoreAsync();
                    }
                    catch (SuspensionManagerException)
                    {
                        //Something went wrong restoring state.
                        //Assume there is no state and continue
                    }
                }

                // Place the frame in the current Window
                Window.Current.Content = rootFrame;
            }
            if (rootFrame.Content == null)
            {
                // When the navigation stack isn't restored navigate to the first page,
                // configuring the new page by passing required information as a navigation
                // parameter
                if (!rootFrame.Navigate(typeof(ComputersTitles), "AllGroups"))
                {
                    throw new Exception("Failed to create initial page");
                }
            }
            // Ensure the current window is active
            Window.Current.Activate();
        }

        /// <summary>
        /// Appelé lorsque l'exécution de l'application est suspendue. L'état de l'application est enregistré
        /// sans savoir si l'application pourra se fermer ou reprendre sans endommager 
        /// le contenu de la mémoire.
        /// </summary>
        /// <param name="sender">Source de la requête de suspension.</param>
        /// <param name="e">Détails de la requête de suspension.</param>
        private async void OnSuspending(object sender, SuspendingEventArgs e)
        {
            var deferral = e.SuspendingOperation.GetDeferral();
            await SuspensionManager.SaveAsync();
            deferral.Complete();
        }


        internal static void removeServer(Server s)
        {
            if (servers != null)
            {
                servers.Remove(s);
                writeServerData();
            }
        }

        internal static void addServer(Server s)
        {
            if (servers == null)
            {
                servers = new List<Server>();
            }
            servers.Add(s);
            writeServerData();
        }

        public static bool updateAvailable { get; set; }
    }
}
